package cn.stylefeng.guns.modular.gridsystem.utils;

import cn.hutool.core.io.FileUtil;

import javax.sound.sampled.*;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.ShortBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class WavTransformUtil {

    public static boolean transWav(File inWavFile, File outWavFile, int sampleRate) throws Exception {

        AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(inWavFile);
        AudioFormat format = audioInputStream.getFormat();

        if (format.getSampleRate() == sampleRate) {
            FileUtil.copy(inWavFile, outWavFile, true);
            return true;
        }
        AudioFormat audioFormat = new AudioFormat(sampleRate, 16, 1, true, false);
        AudioInputStream wavIs = AudioSystem.getAudioInputStream(audioFormat, audioInputStream);


        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[] buf = new byte[2048];
        int len = -1;
        while ((len = wavIs.read(buf)) != -1) {
            bos.write(buf, 0, len);
        }
        return writeWav(bos.toByteArray(), outWavFile, audioFormat) > 0;
    }


    private static int writeWav(byte[] audioData, File target, AudioFormat audioFormat) throws IOException {
        final File parent = target.getParentFile();
        if (!parent.exists()) {
            parent.mkdirs();
        }

        try (ByteArrayInputStream bais = new ByteArrayInputStream(audioData);
             AudioInputStream ais = new AudioInputStream(bais, audioFormat, audioData.length / audioFormat.getFrameSize())) {
            //定义最终保存的文件名
            return AudioSystem.write(ais, AudioFileFormat.Type.WAVE, target);
        } catch (Exception e) {
            return -1;
        }
    }


    public static int toInt(byte[] b) {
        return (((b[3] & 0xff) << 24) + ((b[2] & 0xff) << 16) + ((b[1] & 0xff) << 8) + ((b[0] & 0xff)));
    }

    private static short toShort(byte[] b) {
        return (short)((b[1] << 8) + (b[0]));
    }


    public static byte[] read(RandomAccessFile rdf, int pos, int length) throws IOException {
        rdf.seek(pos);
        byte[] result = new byte[length];
        for (int i = 0; i < length; i++) {
            result[i] = rdf.readByte();
        }
        return result;
    }

    public static short[] bytesToShort(byte[] bytes){
        ByteBuffer buffer = ByteBuffer.wrap(bytes);
        buffer.order(ByteOrder.LITTLE_ENDIAN);
        short[] shorts = new short[bytes.length/2];
        buffer.asShortBuffer().get(shorts);
        return shorts;
    }

    public static int[] mapArr(int min,int max,int[] data,int minMap,int maxMap){

        for (int i = 0; i < data.length; i++) {
            data[i] = (int) ((data[i] - min) * maxMap / (max - min)) + minMap;
        }
        return data;
    }

    public static int mapInt(int min,int max,int data){
        data = (int) ((data - min) * 255.0 / (max - min));
        return data;
    }

    /**
     *数组分割
     * @param bytes
     * @param splitLength 按多少长度分割
     * @return
     */
    public static List<byte[]> splitBytes(byte[] bytes,int splitLength){
        int num = bytes.length / splitLength;
        ArrayList<byte[]> objects = new ArrayList<>();
        for (int i = 0; i < num; i++) {
            byte[] bytes1 = new byte[2048];
            System.arraycopy(bytes,i * 2048,bytes1,0,2048);
            objects.add(bytes1);
        }
        return objects;
    }

    /**
     * 计算平均值
     * @param arr
     * @return
     */
    public static double calculateAverage(float[] arr) {
        double sum = 0;
        for (int i = 0; i < arr.length; i++) {
//            float format = Float.parseFloat(String.format("%.2f", arr[i]));
            sum += arr[i];
        }
        return sum / arr.length;
    }

    /**
     * 计算绝对值平均值
     * @param arr
     * @return
     */
    public static float calculateAbsAverage(float[] arr) {
        float sum = 0;
        for (int i = 0; i < arr.length; i++) {
            sum += Math.abs(arr[i]);
        }
        return sum / arr.length;
    }

    /**
     * 大端转小端
     * @param buffer
     * @return
     */
    public static byte[] leToBeBytes(byte[] buffer,int len) {
        byte[] tempBuffer = new byte[len];
        for (int i = 0; i < len; i+=2) {
            tempBuffer[i] = buffer[i + 1];
            tempBuffer[i + 1] = buffer[i];
        }
        return tempBuffer;
    }


    public static void main(String[] args) throws IOException {
//        File f = new File("D:\\weixin\\WeChat Files\\wxid_l0titbtrkkgm22\\FileStorage\\File\\2022-04\\CBZ (1).wav");
//        RandomAccessFile rdf = null;
//        rdf = new RandomAccessFile(f,"r");
//
//        System.out.println("声音尺寸: " + toInt(read(rdf, 4, 4))); // 声音尺寸
//
//        System.out.println("音频格式: " + toShort(read(rdf, 20, 2))); // 音频格式 1 = PCM
//
//        System.out.println("声道数: " + toShort(read(rdf, 22, 2))); // 1 单声道 2 双声道
//
//        System.out.println("采样率: " + toInt(read(rdf, 24, 4)));  // 采样率、音频采样级别 8000 = 8KHz
//
//        System.out.println("波形的数据量: " + toInt(read(rdf, 28, 4)));  // 每秒波形的数据量
//
//        System.out.println("采样帧: " + toShort(read(rdf, 32, 2)));  // 采样帧的大小
//
//        System.out.println("采样位数: " + toShort(read(rdf, 34, 2)));  // 采样位数
//
//        rdf.close();
        int[] ints = { 0, -80, 54 , 20};
        int[] ints1 = mapArr(0,-80,ints,0,255);
        System.out.println(Arrays.toString(ints1));
    }
}
